package dao

import (
	"fmt"
	"lib/structs/tables"
	"lib/utils"
	"strings"
	"sync"
)

var (
	Cache           = new(cache)
	clientInfoCache sync.Map
	OnlineMap       sync.Map           // 设备最近一次上报消息的时间 map[uniqueCode]int64
	ResCache        sync.Map           // 响应缓存
	Policies        []tables.AmsPolicy // 策略缓存
)

// cache 只考虑本地缓存，模型放大时自行替换这里的缓存为redis，同时替换get，set方法
type cache struct {
}

// LoadClientMap 项目启动时初始化缓存
func (c cache) LoadClientMap() (err error) {
	// 加载客户端信息
	var li []tables.AmsClient
	if err = DB.Model(&tables.AmsClient{}).Find(&li).Error; err != nil {
		return fmt.Errorf("加载 ams client cache err:[%v]", err)
	}
	for _, item := range li {
		clientInfoCache.Store(item.Id, item)
	}

	// 加载策略信息
	err = c.LoadAmsPolicy()
	return nil
}

func (c cache) LoadAmsPolicy() (err error) {
	var l2 []tables.AmsPolicy
	err = DB.Model(&tables.AmsPolicy{}).Find(&l2).Error
	if err != nil {
		return fmt.Errorf("加载 ams policy cache err:[%v]", err)
	}
	Policies = l2

	return nil
}

func (cache) GetClient(id int64) (m tables.AmsClient, b bool) {
	val, b := clientInfoCache.Load(id)
	if b {
		m = val.(tables.AmsClient)
	}
	return
}

func (cache) SetClient(m tables.AmsClient) {
	clientInfoCache.Store(m.Id, m)
}

func (cache) DelClient(id int64) {
	clientInfoCache.Delete(id)
}

// CheckClientSimilarity 检查设备相似度 ，主板、bios、硬盘序列号 和主机名称，4个有三个相同就返回true
func (cache) CheckClientSimilarity(m tables.AmsClient) (ms string) {
	mapStr := make([]string, 0)
	clientInfoCache.Range(func(key, value interface{}) bool {
		item := value.(tables.AmsClient)
		var i int
		if utils.CompareByTrimAndToLower(item.MainBoardSerial, m.MainBoardSerial) {
			i++
		}
		if utils.CompareByTrimAndToLower(item.BiosSerial, m.BiosSerial) {
			i++
		}
		if utils.CompareByTrimAndToLower(item.HardDiskSerial, m.HardDiskSerial) {
			i++
		}
		if utils.CompareByTrimAndToLower(item.Hostname, m.Hostname) {
			i++
		}
		if i >= 3 {
			mapStr = append(mapStr, fmt.Sprintf("%d", item.Id))
		}
		return true
	})
	ids := append(strings.Split(m.MapSimilarity, ","), mapStr...)
	ids = utils.RemoveElementFast(ids, "")
	ms = utils.ArrStringToStr(ids)
	return
}
